import React, { useCallback, useEffect } from 'react';
import {
  CopilotDevConsole,
  CopilotPopup,
  useChatContext,
  WindowProps,
} from '@copilotkit/react-ui';
import { MamisCopilotConfig } from '../types/config';
import { ShadowedWindow } from './ShadowedWindow';
import { ShadowDOMManager } from '../isolation/ShadowDOMManager';
import { useCopilotMessagesContext } from '@copilotkit/react-core';
import {
  ActionExecutionMessage,
  AgentStateMessage,
  ImageMessage,
  Message,
  ResultMessage,
  TextMessage,
} from '@copilotkit/runtime-client-gql';

interface CopilotPopupWrapperProps {
  config: MamisCopilotConfig;
  shadowManager?: ShadowDOMManager;
  onClose?: () => void;
  onMessage?: (message: unknown) => void;
  onPageAction?: (action: string, target: string, result: unknown) => void;
  onError?: (error: Error) => void;
}

export const Header: React.FC = () => {
  const { setOpen, icons, labels } = useChatContext();
  const { messages, setMessages } = useCopilotMessagesContext();

  useEffect(() => {
    const savedMessagesString = localStorage.getItem('mamis-copilot-messages');
    if (!savedMessagesString) {
      return;
    }

    const plainMessageObjects = JSON.parse(savedMessagesString) as Partial<Message>[];
    const messageObjects = new Array<Message>();
    for (const plainMessageObject of plainMessageObjects) {
      let message: Message;
      switch (plainMessageObject.type) {
        case 'ActionExecutionMessage':
          message = new ActionExecutionMessage(plainMessageObject as ActionExecutionMessage);
          break;
        case 'AgentStateMessage':
          message = new AgentStateMessage(plainMessageObject as AgentStateMessage);
          break;
        case 'ImageMessage':
          message = new ImageMessage(plainMessageObject as ImageMessage);
          break;
        case 'ResultMessage':
          message = new ResultMessage(plainMessageObject as ResultMessage);
          break;
        case 'TextMessage':
          message = new TextMessage(plainMessageObject as TextMessage);
          break;
        default:
          message = new TextMessage(plainMessageObject as TextMessage);
          break;
      }
      messageObjects.push(message);
    }
    setMessages(messageObjects);
  }, [setMessages]);

  useEffect(() => {
    // 将 messages 保存到 localStorage
    localStorage.setItem('mamis-copilot-messages', JSON.stringify(messages));
  }, [messages, setMessages]);

  return (
    <div className="copilotKitHeader">
      <div>{labels.title}</div>
      <div className="copilotKitHeaderControls">
        <CopilotDevConsole />
        <button
          onClick={() => {
            localStorage.setItem('mamis-copilot-messages', '[]');
            setMessages([]);
          }}
          aria-label="Reset"
          className="copilotKitHeaderCloseButton"
          style={{ marginTop: '-3px' }}
        >
          {icons.regenerateIcon}
        </button>
        &nbsp;
        <button
          onClick={() => setOpen(false)}
          aria-label="Close"
          className="copilotKitHeaderCloseButton"
        >
          {icons.headerCloseIcon}
        </button>
      </div>
    </div>
  );
};

export const CopilotPopupWrapper: React.FC<CopilotPopupWrapperProps> = ({
  config,
  shadowManager,
}) => {
  // 创建自定义Window组件，传入shadowManager引用
  const Window = useCallback(
    (props: WindowProps) => {
      return React.createElement(ShadowedWindow, {
        ...props,
        shadowManager: shadowManager,
      });
    },
    [shadowManager]
  );

  let defaultOpen = config.popup.defaultOpen;
  const savedPopupState = localStorage.getItem('mamis-copilot-popup-last-state');
  if (savedPopupState) {
    defaultOpen = savedPopupState === 'open';
  }

  const onSetOpen = useCallback((open: boolean) => {
    localStorage.setItem('mamis-copilot-popup-last-state', open ? 'open' : 'closed');
  }, []);

  return (
    <CopilotPopup
      instructions={config.popup.instructions}
      labels={config.popup.labels}
      defaultOpen={defaultOpen}
      hitEscapeToClose={config.popup.hitEscapeToClose}
      clickOutsideToClose={config.popup.clickOutsideToClose}
      hideStopButton={config.popup.hideStopButton}
      imageUploadsEnabled={config.popup.imageUploadsEnabled}
      Window={Window}
      Header={Header}
      onSetOpen={onSetOpen}
    />
  );
};

export default CopilotPopupWrapper;
